<?php

namespace App\Services\Api;
use App\Models\ChatMsg;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;

class ChatSwooleService extends ApiService
{

    /**
     * 建立连接
     * @method onOpen
     * @author chengzhigang<1256699215@qq.com>
     */
    public function onOpen($serv, $request)
    {
        Log::info('onOpen');
        $param = $request->get;
        $room_id = $param['room_id'];
        $userInfo = AuthService::getUser($param['token']);
        if(empty($userInfo)){
            return ['status'=>2,'msg'=>'登录失败','data'=>['active'=>'connect','data'=>[]]];
        }
        $result = $this->getChatHistory($serv,$room_id,$userInfo['id']);
        $serv->bind($request->fd,$userInfo['id']);
        $this->addRoom($room_id,$request->fd,$userInfo['id']);//加入房间
        return ['status'=>1,'msg'=>'请求成功','data'=>['active'=>'connect','data'=>$result]];
    }

    public function onMessage($serv, $frame)
    {
        $data = json_decode($frame->data,true);
        $room_id = $data['room_id'];
        $userInfo = AuthService::getUser($data['token']);
        if(empty($userInfo)){
            return ['status'=>2,'msg'=>'登录失败','data'=>['active'=>'connect','data'=>[]]];
        }
        $result = [];
        if($data['active']=='send'){
            $result = $this->addMsg($room_id,$data,$userInfo);
        }
        return ['status'=>1,'msg'=>'请求成功','data'=>['active'=>$data['active'],'data'=>$result]];
    }

    //加入房间
    public function addRoom($room_id,$fd,$user_id){
        $roomInfo = [
            'room_id' => $room_id,
            'fd' => $fd,
            'user_id' => $user_id
        ];
        Redis::hSet('ChatRoom:'.$room_id,$user_id,json_encode($roomInfo));
    }

    //获取历史聊天
    public function getChatHistory($serv,$room_id,$user_id){
        $speckData = Redis::lRange('ChatRecord:' . $room_id,0,-1);
        if(empty($speckData)){
            $chatRecord = ChatMsg::from('chat_msg as a')->join('user_info as b','a.user_id','=','b.id')->where('a.chat_id',$room_id)->select(['a.chat_id as room_id','a.user_id','a.msg_type','a.content as msg','b.avatar','a.create_time as time'])->orderBy('a.create_time','asc')->get()->toArray();
            foreach($chatRecord as $val){
                Redis::rPush('ChatRecord:'.$room_id,json_encode($val));
            }
            $speckData = Redis::lRange('ChatRecord:' . $room_id,0,-1);
        }
        $redisData = Redis::lRange('ChatRoomMsg:' . $room_id,0,-1);
        $data = array_merge($speckData,$redisData);
        $historySpeck = [];
        foreach($data as $v){
            $v = json_decode($v,true);
            if($v['user_id']==$user_id){
                $v['own'] = true;
            }else{
                $v['own'] = false;
            }
            $historySpeck[] = $v;
        }
        return $historySpeck;
    }

    //存储聊天
    public function addMsg($room_id,$data,$user){
        $msg = "";
        switch ($data['msg_type']){
            case 'text':
                $msg = $data['msg'];
                break;
            case 'image':
                $result = $this->uploadBase64Img($data['msg']);
                if($result['status']==2){
                    var_dump('图片上传失败');
                    return [];
                }
                $msg = $result['data'];
                break;
            case 'emoji':
                $msg = $data['msg'];
                break;
            default :
                var_dump('消息类型不支持');
                break;
        }
        $speckInfo = [
            'room_id' => $room_id,
            'user_id'=>$user['id'],
            'msg' => $msg,
            'msg_type'=>$data['msg_type'],
            'avatar' => $user['avatar'],
            'time' => date('Y-m-d H:i:s'),
        ];
        Redis::rPush('ChatRoomMsg:'.$room_id,json_encode($speckInfo));
        return $speckInfo;
    }

    public function onClose($serv, $fd)
    {
        Log::info('onClose');
        echo "标识{$fd}关闭了连接\n";
    }

    public function onRequest($request, $response)
    {
        Log::info('onRequest');
    }

    private function uploadBase64Img($base64Img){
        $base64_img = trim($base64Img);
        if(preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_img, $result)){
            $type = $result[2];
            if(in_array($type,['pjpeg','jpeg','jpg','gif','bmp','png'])){
                $fileDir = 'uploads/chat/'.date('Ymd');
                $filename = uniqid() . '.'.$type;
                $filePath = $fileDir . '/' . $filename;
                if (Storage::disk('public')->put($filePath, base64_decode(str_replace($result[1], '', $base64_img)))) {
                    $savePath = Storage::url($filePath);
                    $absolutePath = config('const.img_url').$savePath;
                    return ['status' => 1, 'msg' => '上传成功', 'data' => $absolutePath];
                } else {
                    return ['status' => 2, 'msg' => '上传失败', 'data' => []];
                }
            }else{
                //文件类型错误
                return ['status' => 2, 'msg' => '图片上传类型错误', 'data' => []];
            }
        }else{
            return ['status' => 2, 'msg' => '图片格式错误', 'data' => []];
        }
    }

    //定时更新聊天记录
    public function updateChatRecord(){
        $room_id = 1;
        $speckData = Redis::lRange('ChatRoomMsg:' . $room_id,0,-1);
        $historySpeck = [];
        foreach($speckData as $v){
            $v = json_decode($v,true);
            $historySpeck[] = [
                'chat_id' => $room_id,
                'user_id' => $v['user_id'],
                'msg_type' => $v['msg_type'],
                'content' => $v['msg'],
                'create_time' => $v['time']
            ];
        }
        $chatMsg = new ChatMsg();
        $chatMsg->addAll($historySpeck);
        Redis::del('ChatRecord:'.$room_id);
        Redis::del('ChatRoomMsg:'.$room_id);
    }
}
